from direct.actor import Actor
from pandac.PandaModules import *
from direct.interval.MetaInterval import *
from direct.interval.IntervalGlobal import *

from direct.showbase import DirectObject

import maultasche as mt


class Picker(DirectObject.DirectObject):
   def __init__(_):
      #setup collision stuff

      _.picker= CollisionTraverser()
      _.queue=CollisionHandlerQueue()

      _.pickerNode=CollisionNode('mouseRay')
      _.pickerNP=camera.attachNewNode(_.pickerNode)

      _.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())

      _.pickerRay=CollisionRay()

      _.mapPlane = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0)))
     
      _.pickerNode.addSolid(_.pickerRay)

      #_.picker.addCollider(_.pickerNode, _.queue)
      _.picker.addCollider(_.pickerNP, _.queue)
      
      #this holds the object that has been picked
      _.pickedObj=None
      _.pickedCompany=None

      _.companies = []
      _.cities = []

      _.accept('mouse1', _.printMe)
      _.accept('mouse3', _.moveMe)
    
      from direct.gui.OnscreenText import OnscreenText
      _.readout = OnscreenText(text = 'Nothing selected.', mayChange=True,
    pos = (0.7, -0.6), scale = 0.05, bg=(0.3,0.3,0.4,0.8))


   #this function is meant to flag an object as being somthing we can pick
   def makePickable(_,newObj):
      newObj.setTag('pickable','true')

   #this function finds the closest object to the camera that has been hit by our ray
   def getObjectHit(_, mpos): #mpos is the position of the mouse on the screen
      _.pickedObj=None #be sure to reset this
      _.pickedCompany=None
      _.pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY())
      _.picker.traverse(render)
      if _.queue.getNumEntries() > 0:
         _.queue.sortEntries()
         
         collision = _.queue.getEntry(0)
         _.pickedObj= collision.getIntoNodePath()

         parent=_.pickedObj.getParent()
         _.pickedObj=None
         _.pickedCompany=None

         while parent != render:
            if parent.getTag('pickable')=='true':
##               if parent.company:
##                    _.pickedObj=parent
##                    return company
##               else:
                    _.pickedObj=parent
                    company = _.pickedObj.getTag('company')
                    city = _.pickedObj.getTag('city')
                    if company:
                        # try to find this unit's company
                        # select the company instead
                        _.pickedCompany=_.companies[int(company)]
                        
                        # update on-screen info
                        _.readout['text'] = "Company\nID: %s Player: %s\n%s - %s : %s \n" % (
                            _.pickedCompany.id,
                            _.pickedCompany.player.name,
                            _.pickedCompany.front[0].name,
                            _.pickedCompany.flank[0].name,
                            _.pickedCompany.officer.name
                            )
                    elif city:
                        _.pickedCity = _.cities[int(city)]

                        # update on-screen info
                        _.readout['text'] = "City\nID: %s Player: %s\n%s\n%s" % (
                            _.pickedCity.id,
                            _.pickedCity.player.name,
                            _.pickedCity.name,
                            mt.tables.ranks["city"][_.pickedCity.rank]
                            )
                        
                    return parent
            else:
               parent=parent.getParent()
      
      _.readout['text'] = "Nothing selected."
      return None


   def getPickedObj(_):
         return _.pickedObj

   def printMe(_):
      if base.mouseWatcherNode.hasMouse():
           print "parent ", _.getObjectHit( base.mouseWatcherNode.getMouse())
           print _.pickedObj
        
   def moveMe(_):
      if _.pickedObj or _.pickedCompany:
        maus = base.mouseWatcherNode.getMouse()
        _.destObj=None #be sure to reset this
        _.pickerRay.setFromLens(base.camNode, maus.getX(),maus.getY())
        _.picker.traverse(render)
        dest = None

        if _.queue.getNumEntries() > 0:
            _.queue.sortEntries()
         
            collision = _.queue.getEntry(0)
            print collision
            _.destObj= collision.getIntoNodePath()
            
            if _.destObj.getName() == "terrain":
                dest = collision.getSurfacePoint(render)
		dest.setZ(1)

        if not dest:
            return

        #if isinstance(_.pickedObj, mt.Unit):
        dist = dest - _.pickedObj.getPos()
        eta = dist.length() / 3.0
        
##        dest = NodePath
        if _.pickedCompany is None:
            #_.pickedObj.setPos(maus.getX(),maus.getY(),0) #FIXME
            myInterval= _.pickedObj.posInterval(eta,
                dest)#, startPos=_.pickedObj.getPos())
            #_.pickedObj.lookAt(dest)
            #rotInterval= _.pickedObj.hprInterval(3.0,
            #    dist * 10)
            #rotSequence = Sequence(rotInterval)
            #rotSequence.start()
            _.pickedObj.lookAt(dest)
        
            flag = loader.loadModel('./models/flag')
            flag.setPos(dest)
            flag.reparentTo(render)

            mySequence = Sequence(myInterval,
                                  Func(flag.removeNode))
            #mySequence = Sequence(rotInterval, myInterval)
            mySequence.start()
        else:
            _.pickedCompany.goTo(dest)

        print "zoom! " + str(eta) + " units travelled!"
        #else:
        #    print "tried to move immobile object :/"
        
##        _.pickedObj=None #be sure to reset this
##        _.pickerRay.setFromLens(base.camNode, maus.getX(),maus.getY())
##        _.picker.traverse(render)
##        if _.queue.getNumEntries() > 0:
##            _.queue.sortEntries()
##            _.entry = _.queue.getEntry(0)
##            _.pickedObj=_.entry.getIntoNodePath()
##
##            parent=_.pickedObj.getParent()
##            _.pickedObj=None
##
##            while parent != render:
##                if isinstance(parent, CollisionPlane):
##                    _.pickedObj=parent
##                    return parent
##                else:
##                    parent=parent.getParent()

      else:
        print "No object picked :(" 

